/*
 *   AS IS License 
 *  ==Naive Coders==
 */
package com.naivecoders.refex;

import com.naivecoders.refex.functions.AbstractFunction;
import com.naivecoders.refex.functions.FCode;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.List;

/**
 *
 * @author andrew
 */
public class InvocationBuilder extends FunctionBuilder{
    private final Deque<FunctionBuilder> builderStack = new ArrayDeque<>();

    public InvocationBuilder( FunctionFactory factory) {
        super(factory);
    }

    @Override
    public AbstractFunction build() throws InternalTypeCheckException {
        openList();
        openList();
        put(FCode.P);
        openList();
        put(FCode.S);
        put(getArguments());
        closeList();
        put(FCode.I);
        closeList();
        
        return topBuilder().build();
    }
    
    private FunctionBuilder topBuilder() {
       return  builderStack.peek();
    }
    
    private void put(List<AbstractFunction> fns) {
        for (AbstractFunction fn: fns) {
        topBuilder().add(fn);
        }
    }
    private void put(FCode c) throws InternalTypeCheckException {
        topBuilder().add(new FName(c));
    }
    private void openList() throws InternalTypeCheckException {
        builderStack.push(new FunctionBuilder(getFactory()));
        put(FCode.I);
    }
    
    private void closeList() throws InternalTypeCheckException {
        final AbstractFunction fnc = builderStack.pop().build();
        topBuilder().add(fnc);
    }
}
